<?php
namespace Dao;

use Core\HHO;

class Session {
	/**
	 * 会话数据文件名。
	 * @var string
	 */
	private $files = NULL;
	/**
	 * 会话数据。
	 * @var array
	 */
	private $data = NULL;

	/**
	 * 恢复指定用户的会话。
	 * @param string $user
	 */
	private function __construct($sid) {
		$dir = HHO::$config['runtime.root'] . '/SESS';
		
		is_dir($dir) || mkdir($dir, NULL, TRUE);
		
		$this->files = $dir . '/' . $sid;
		
		if (is_file($this->files)) {
			$this->data = json_decode(file_get_contents($this->files), TRUE);
		} else {
			$this->data = [];
			file_put_contents($this->files, '[]');
		}
	}

	/**
	 * 设置会话的目标搜索地区和日期。
	 *
	 * @param string $from
	 * @param string $to
	 * @param string $dater
	 * @return boolean
	 */
	public function setTicket($from, $to, $dater) {
		$this->data['from'] = $from;
		$this->data['to'] = $to;
		$this->data['dater'] = $dater;
		
		return file_put_contents($this->files, json_encode($this->data, JSON_UNESCAPED_UNICODE)) > 0;
	}

	/**
	 * 获得会话的目标搜索地区和日期。
	 *
	 * @return array
	 */
	public function getTicket() {
		if (!isset($this->data['from'])) {
			return [];
		}
		
		return ['from' => $this->data['from'], 'to' => $this->data['to'], 'dater' => $this->data['dater']];
	}

	/**
	 * 添加一个过滤掉的车次。
	 *
	 * @param string $no
	 * @param string $seat
	 * @param int $expire
	 * @return boolean
	 */
	public function addFilter($no, $seat = '-', $expire = 60) {
		isset($this->data['filter']) || $this->data['filter'] = [];
		
		isset($this->data['filter'][$no]) || $this->data['filter'][$no] = [];
		
		$this->data['filter'][$no][$seat] = time() + $expire;
		
		return file_put_contents($this->files, json_encode($this->data, JSON_UNESCAPED_UNICODE)) > 0;
	}

	/**
	 * 获得所有过滤掉的车次。
	 *
	 * @return array
	 */
	public function getFilter() {
		if (!isset($this->data['filter'])) {
			return [];
		}
		
		$current = time();
		
		foreach ($this->data['filter'] as $no => &$seats) {
			foreach ($seats as $seat => $expire) {
				if ($expire < $current) {
					unset($seats[$seat]);
				}
			}
			
			if (count($seats) == 0) {
				unset($this->data['filter'][$no]);
			}
		}
		
		if (!file_put_contents($this->files, json_encode($this->data, JSON_UNESCAPED_UNICODE)) > 0) {
			return [];
		}
		
		return $this->data['filter'];
	}

	/**
	 * 设置当前会话的12306用户。
	 *
	 * @param string $user
	 * @return boolean
	 */
	public function setUser($user) {
		$this->data['user'] = trim($user);
		
		return file_put_contents($this->files, json_encode($this->data, JSON_UNESCAPED_UNICODE)) > 0;
	}

	/**
	 * 获得当前会话的12306用户。
	 *
	 * @return string
	 */
	public function getUser() {
		if (isset($this->data['user'])) {
			return $this->data['user'];
		}
		
		return '';
	}

	/**
	 * 设置可预订的单子，包括待预订的车次以及旅客信息；如果 $order 参值为空，则清空单子。
	 *
	 * @param array $passenger
	 * @return boolean
	 */
	public function setOrder($order = NULL) {
		if ($order) {
			$this->data['order'] = $order;
		} else {
			unset($this->data['order']);
		}
		
		return file_put_contents($this->files, json_encode($this->data, JSON_UNESCAPED_UNICODE)) > 0;
	}

	/**
	 * 获得可预订的单子信息。
	 *
	 * @return array
	 */
	public function getOrder() {
		if (isset($this->data['order'])) {
			return $this->data['order'];
		}
		
		return [];
	}

	/**
	 * 销毁会话。
	 *
	 * @return boolean
	 */
	public function destruct() {
		if (is_file($this->files)) {
			$this->data = [];
			return unlink($this->files);
		}
		
		return TRUE;
	}

	public static function getInstance($sid) {
		$sid = trim($sid);
		if (!$sid) {
			return FALSE;
		}
		
		static $instance = [];
		
		if (!isset($instance[$sid])) {
			$instance[$sid] = new self($sid);
		}
		
		return $instance[$sid];
	}
}